namespace SimpleWebServices.Net
{
    using System;
    using System.Globalization;
    using System.Net;
    using System.Reflection;
    using System.Xml;
    using SimpleWebServices.Configuration;
    using SimpleWebServices.Data;

    public sealed class HttpRequestDefinition
    {
        private static string _userAgent;
        private AbsoluteUri _uri;

        public HttpRequestDefinition()
            : this(null)
        {
        }

        public HttpRequestDefinition(AbsoluteUri uri)
        {
            this.Headers = new DataCollection();
            this.Accept = "*/*";
            this.Method = "GET";
            this.Uri = uri;
        }

        public string Accept
        {
            get
            {
                return this.Headers["Accept"];
            }

            set
            {
                this.Headers["Accept"] = value;
            }
        }

        public string ContentType
        {
            get
            {
                return this.Headers["Content-Type"];
            }

            set
            {
                this.Headers["Content-Type"] = value;
            }
        }

        public CookieContainer Cookies
        {
            get;
            set;
        }

        public string Method
        {
            get;
            set;
        }

        public DataCollection Headers
        {
            get;
            set;
        }

        public AbsoluteUri Uri
        {
            get
            {
                return this._uri;
            }

            set
            {
                if (null == value)
                {
                    throw new ArgumentNullException("value");
                }

                this._uri = value;
            }
        }

        private static string UserAgent
        {
            get
            {
                if (null == _userAgent)
                {
                    Version version = Assembly.GetExecutingAssembly().GetName().Version;
                    _userAgent = string.Format(CultureInfo.InvariantCulture, "SimpleWebServices.Testing/{0}.{1} (webmaster@simplewebservices.org)", XmlConvert.ToString(version.Major), XmlConvert.ToString(version.Minor));
                }

                return _userAgent;
            }
        }

        public WebRequest ToWebRequest()
        {
            if (TestingConfiguration.Settings().Http.ConsoleWrite)
            {
                Console.WriteLine(string.Concat(this.Method, " ", this.Uri));
            }

            HttpWebRequest result = (HttpWebRequest)WebRequest.Create((Uri)this.Uri);
            result.AllowAutoRedirect = false;
            result.Method = this.Method;
            result.UserAgent = HttpRequestDefinition.UserAgent;
            result.CookieContainer = this.Cookies;

            foreach (var datum in this.Headers)
            {
                switch (datum.Key)
                {
                    case "Accept":
                        result.Accept = datum.Value;
                        break;

                    case "Content-Type":
                        result.ContentType = datum.Value;
                        break;

                    default:
                        result.Headers.Add(datum.Key, datum.Value);
                        break;
                }
            }

            return result;
        }
    }
}